Skip to content

Tornado 基于协程的server实现

Tornado 基于协程的server实现

一个简单的Hello World示例

    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("Hello, world")

    application = tornado.web.Application([
        (r"/", MainHandler)
    ], debug=True)

    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()

服务如何跑起来

    class Application(object):
        def __init__(self, handlers=None, ···):
            ···
            self.handlers = []
            ···
            if handlers: self.add_handlers(".*$", handlers)
            ···

        def add_handlers(self, host_pattern, host_handlers):
            ···
            handlers = []
            self.handlers.append((re.compile(host_pattern), handlers))
            for spec in host_handlers:
                ···
                spec = URLSpec(pattern, handler, kwargs)
                handlers.append(spec)
                ···

        def listen(self, port, address="", **kwargs):
            from tornado.httpserver import HTTPServer
            server = HTTPServer(self, **kwargs)
            server.listen(port, address)

    class IOLoop(object):
        def start(self):
            while True:
                ···
                callbacks = self._callbacks
                self._callbacks = []
                for callback in callbacks:
                self._run_callback(callback)
                ···
                event_pairs = self._impl.poll(poll_timeout)
                self._events.update(event_pairs)
                while self._events:
                    fd, events = self._events.popitem()
                    self._handlers[fd](fd, events)
                ··· 
至此,工程跑起了一个事件循环ioloop,保存了一个url与view(RequestHandler)对应关系的list,生成了一个监听socket并将其加入到ioloop中
## 如何处理请求
```python
    class HTTPServer(object):
        def start():
            ···
            self.io_loop.add_handler(fd, self._handle_events, ioloop.IOLoop.READ)

        def _handle_events(self, fd, events):
            while True:
                ···
                connection, address = self._sockets[fd].accept() 
                ···
                stream = iostream.IOStream(connection, io_loop=self.io_loop)
                HTTPConnection(stream, address, self.request_callback, self.no_keep_alive, self.xheaders)
                ···

如何返回结果

    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("Hello, world")

    class RequestHandler(object):
        def write(self, chunk):
            self._write_buffer.append(chunk)

如何处理异步

@gen.coroutine
def get():
    ···
    yield func()
    ···

模块简述

# 提供用户使用接口
Application()
RequestHandler()

# 管理listen_socket的行为
HTTPServer()

# 保存url <-> RequestHandler对应关系
URLSpec()

# 管理 http 链接
HTTPConnection()

# 管理 conn_socket 的行为
IOStream()

# request -> dict
HTTPRequest()

# 事件循环
IOLoop()